package com.saicmotor.workmanager;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.Observer;
import androidx.work.BackoffPolicy;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;
import androidx.work.WorkQuery;
import androidx.work.WorkRequest;

import android.os.Bundle;

import com.google.common.util.concurrent.ListenableFuture;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 使用workManager调度work，WorkRequest执行具体的任务，可选定期执行，或执行一次
        WorkRequest upload=new OneTimeWorkRequest.Builder(UploadWorker.class).build();
        // 将WorkRequest提交到WorkManager
        WorkManager.getInstance(this).enqueue(upload);

        // 笔记
        // 1.WorkRequest
        // 1.1.1一次性任务
        WorkRequest wr1 = OneTimeWorkRequest.from(UploadWorker.class);
        // 复杂的任务可用构建器
        WorkRequest wr2=new OneTimeWorkRequest.Builder(UploadWorker.class).build();
        // 1.1.2定期任务
        PeriodicWorkRequest pwr1 =
                new PeriodicWorkRequest.Builder(UploadWorker.class, 1, TimeUnit.HOURS)
                        .build();
        // 下面的表示在每小时最后15分钟内运行任务
        WorkRequest pwr2 =
                new PeriodicWorkRequest.Builder(UploadWorker.class,
                        1, TimeUnit.HOURS,
                        15, TimeUnit.MINUTES)
                        .build();

        // 1.2.工作约束
        Constraints constraints = new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.UNMETERED)
                .setRequiresCharging(true)
                .build();
        WorkRequest wr3 =
                new OneTimeWorkRequest.Builder(UploadWorker.class)
                        .setConstraints(constraints)
                        .build();

        // 1.3.延迟工作
        WorkRequest wr4 =
                new OneTimeWorkRequest.Builder(UploadWorker.class)
                        .setInitialDelay(10, TimeUnit.MINUTES)
                        .build();

        // 1.4.重试和退避，让WorkManager重试工作，可以让worker返回Result.retry()，
        // 设置退避延迟时间和退避政策
        WorkRequest wr5 =
                new OneTimeWorkRequest.Builder(UploadWorker.class)
                        .setBackoffCriteria(
                                BackoffPolicy.LINEAR,
                                OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                                TimeUnit.MILLISECONDS)
                        .build();
        // 1.5.标记WorkRequest
        WorkRequest wr6 =
                new OneTimeWorkRequest.Builder(UploadWorker.class)
                        .addTag("tag1")
                        .build();

        // 1.6.分配输入数据
        WorkRequest wr7 =
                new OneTimeWorkRequest.Builder(UploadWorker.class)
                        .setInputData(
                                new Data.Builder()
                                        .putString("IMAGE_URI", "http://...")
                                        .build()
                        )
                        .build();


        // 2.work状态
        // 一次性：ENQUEUED、RUNNING、SUCCEEDED、FAILED、CANCELLED
        // 定期：ENQUEUED、RUNNING、CANCELLED

        // 3.任务管理
        // 3.1.唯一任务
        // 唯一任务可确保同一时刻只有一个具有特定名称的工作实例
        // .enqueueUniqueWork() .enqueueUniquePeriodicWork
        // existingWorkPolicy冲突解决政策：REPLACE、KEEP、APPEND
        WorkManager.getInstance(this).enqueueUniquePeriodicWork(
                "test",
                ExistingPeriodicWorkPolicy.KEEP,
                pwr1);

        // 4.观察任务状态
        WorkManager workManager=WorkManager.getInstance(this);
        // 返回ListenableFuture<WorkInfo>
        workManager.getWorkInfoById(pwr1.getId());

        workManager.getWorkInfosForUniqueWork("test");

        workManager.getWorkInfosByTag("tag1");

        // 下述代码的作用是查找带有“syncTag”标记、处于 FAILED 或 CANCELLED 状态，且唯一工作名称为“preProcess”或“sync”的所有任务。
        WorkQuery workQuery = WorkQuery.Builder
                .fromTags(Arrays.asList("syncTag"))
                .addStates(Arrays.asList(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED))
                .addUniqueWorkNames(Arrays.asList("preProcess", "sync")
                )
                .build();

        ListenableFuture<List<WorkInfo>> workInfos = workManager.getWorkInfos(workQuery);

        // 5.取消停止任务
        // 当任务停止后，WorkManager 会立即调用 ListenableWorker.onStopped()关闭可能保留的所有资源
        workManager.cancelWorkById(pwr1.getId());

        workManager.cancelUniqueWork("test");

        workManager.cancelAllWorkByTag("tag1");

        // 6.观察任务的进度
        // 可以使用ListenableWorker或Worker的setProgressAsync() 方法来更新异步过程的进度
        WorkRequest wr8 =
                new OneTimeWorkRequest.Builder(ProgressWorker.class)
                        .addTag("tag2")
                        .build();
        WorkManager.getInstance(getApplicationContext()).getWorkInfoByIdLiveData(wr8.getId())
                .observe(this, new Observer<WorkInfo>() {
                    @Override
                    public void onChanged(@Nullable WorkInfo workInfo) {
                        if (workInfo != null) {
                            Data progress = workInfo.getProgress();
                            int value = progress.getInt("PROGRESS", 0);
                        }
                    }
                });
    }
}